<template>
  <div class="app-container">
    <el-row type="flex" justify="center" align="middle">
      <el-col :span="24">
        <el-card class="box-card">
          <div slot="header">
            <div class="title-box" style="padding-top: 10px; padding-bottom: 13px;">
              <span>菜单管理</span>
            </div>
          </div>
          <el-input v-model="filterOrgText" class="mgb-15" :placeholder="filterPlaceholderText" />
          <div style="margin-bottom: 10px;" />
          <el-tree
            ref="menuTreeRef"
            v-loading="viewLoading"
            :filter-node-method="filterNode"
            :data="menuTree"
            :props="treeProps"
            node-key="id"
            default-expand-all
            :expand-on-click-node="false"
          >
            <span slot-scope="{ node, data }" class="custom-tree-node">
              <span>
                <span v-if="data.type==menuType.TOP" class="mgl-10"><span class="top-title">{{ data.name }}</span><el-tag class="mgl-10" type="success" size="mini">顶级菜单</el-tag></span>
                <span v-if="data.type==menuType.MENU" class="mgl-10"><span class="menu-title">{{ data.name }}</span><el-tag class="mgl-10" type="warning" size="mini">一级菜单</el-tag></span>
                <span v-else-if="data.type==menuType.ITEM" class="mgl-10"><span class="item-title">{{ data.name }}</span><el-tag class="mgl-10" type="danger" size="mini">子菜单</el-tag></span>
                <span v-else-if="data.type==menuType.BUTTON" class="mgl-10"><span class="button-title">{{ data.name }}</span><el-tag class="mgl-10" type="danger" size="mini">按钮</el-tag></span>
              </span>
              <span>
                <el-tooltip v-if="data.type!=menuType.BUTTON" v-perm="['permission-insert']" :content="buttonName(buttonType.ADD,data.type)" placement="top">
                  <el-button type="text" size="mini" icon="el-icon-plus" @click="handleAddButton(data)" />
                </el-tooltip>
                <el-tooltip v-if="data.type!=menuType.TOP" v-perm="['permission-update']" :content="buttonName(buttonType.UPDATE,data.type)" placement="top">
                  <el-button class="update-btn" type="text" size="mini" icon="el-icon-edit" @click="handleUpdateButton(data)" />
                </el-tooltip>
                <el-tooltip v-if="data.type!=menuType.TOP" v-perm="['permission-delete']" :content="buttonName(buttonType.DELETE,data.type)" placement="top">
                  <el-button class="delete-btn" type="text" size="mini" icon="el-icon-delete" @click="handleDeleleButton(data)" />
                </el-tooltip>
              </span>
            </span>
          </el-tree>
        </el-card>
      </el-col>
    </el-row>
    <!--弹窗：新增或编辑权限-->
    <el-dialog :title="textMap[dialogStatus]" :visible.sync="dialogFormVisible" width="80%" :close-on-click-modal="false">
      <el-form ref="dataForm" :model="temp" :rules="menuRules" label-position="top">
        <el-form-item v-if="dialogStatus=='updateButton'" label="节点ID">
          <el-input v-model="temp.id" disabled />
        </el-form-item>
        <el-form-item label="名称" prop="name">
          <el-input v-model="temp.name" />
        </el-form-item>
        <el-form-item label="父级节点">
          <el-input v-model="temp.parent_name" :disabled="true" />
        </el-form-item>
        <el-form-item label="菜单类型">
          <el-select v-model="temp.type" placeholder="请选择菜单类型">
            <el-option label="根目录" value="top" disabled />
            <el-option label="一级菜单" value="root" :disabled="!enableType.menuEnable" />
            <el-option label="子菜单" value="menu" :disabled="!enableType.itemEnable" />
            <el-option label="按钮" value="button" :disabled="!enableType.buttonEnable" />
          </el-select>
        </el-form-item>
        <el-form-item v-if="temp.type===menuType.BUTTON" label="API标识" prop="api_name">
          <el-tooltip content="用于前端页面中按钮权限标识" placement="top-end" effect="light">
            <el-input v-model="temp.api_name" />
          </el-tooltip>
        </el-form-item>
        <el-form-item v-if="temp.type!==menuType.BUTTON" label="路由地址" prop="page_url">
          <el-tooltip content="用于前端页面中与路由匹配的路径标识" placement="top-end" effect="light">
            <el-input v-model="temp.page_url" />
          </el-tooltip>
        </el-form-item>
        <el-form-item label="图标" prop="icon">
          <el-popover ref="popover" placement="top" title="菜单图标" width="630" trigger="focus">
            <div class="grid">
              <div v-for="item of svgIcons" :key="item">
                <el-tooltip placement="top">
                  <div slot="content">
                    {{ item }}
                  </div>
                  <div class="icon-item" @click="temp.icon=item">
                    <svg-icon :icon-class="item" class-name="disabled" />
                  </div>
                </el-tooltip>
              </div>
            </div>
          </el-popover>
          <el-input v-model="temp.icon" v-popover:popover />
        </el-form-item>
        <el-form-item label="颜色">
          <el-color-picker v-model="temp.color" />
        </el-form-item>
        <el-form-item label="顺序" prop="sort">
          <el-input v-model="temp.sort" type="number" />
        </el-form-item>
        <el-form-item label="描述">
          <el-input v-model="temp.description" type="textarea" placeholder="请输入描述或备注" />
        </el-form-item>
        <el-form-item label="显示菜单">
          <el-switch v-model="showMenu" />
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogFormVisible = false">取消</el-button>
        <el-button v-if="dialogStatus=='addButton'" type="primary" @click="addButton">确定</el-button>
        <el-button v-if="dialogStatus=='updateButton'" type="primary" @click="updateButton">确定</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { mapGetters } from 'vuex'
import menuApi from '@/api/menu'
import svgIcons from '@/utils/svg-icons'
import { root, confirm, menuType, buttonType } from '@/utils/constants'
import { parseTime, resetTemp } from '@/utils'
import debounce from 'lodash/debounce'

const topMenu = [{
  id: 0,
  name: '所有',
  description: '顶级菜单',
  parent_id: null,
  level: 0,
  type: 'top',
  sort: 0
}]
export default {

  name: 'MenuManage',
  data() {
    return {
      menuRules: {
        name: [{ required: true, message: '必填', trigger: 'blur' }],
        page_url: [{ required: true, message: '必填', trigger: 'blur' }],
        api_name: [{ required: true, message: '必填', trigger: 'blur' }],
        sort: [{ required: true, message: '必填', trigger: 'blur' }]
      },
      viewLoading: false,
      tableQuery: {
        nick: null
      },
      svgIcons,
      menuType,
      buttonType,
      filterPlaceholderText: '输入节点名称过滤',
      filterOrgText: '',
      menuTree: [],
      treeProps: {
        label: 'name',
        children: 'children'
      },
      dialogFormVisible: false,
      dialogStatus: '',
      temp: {
        idx: null,
        id: null,
        name: null,
        description: null,
        parent_id: null,
        parent_name: null,
        parent: null,
        level: null,
        is_show: null,
        api_name: null,
        page_url: null,
        type: null,
        color: null,
        icon: null,
        sort: null
      },
      showMenu: true,
      enableType: {
        menuEnable: false,
        itemEnable: false,
        buttonEnable: false
      },
      textMap: {
        addButton: '添加菜单',
        updateButton: '更新菜单',
        deleteButton: '删除菜单'
      }
    }
  },

  created() {
    this.fetchData()
  },

  watch: {
    'filterOrgText': debounce(function(val) {
      this.$refs.menuTreeRef.filter(val)
    }, 600)
  },

  methods: {
    // 查询
    fetchData() {
      this.viewLoading = true
      this.menuTree = topMenu
      menuApi.findMenuTree().then(res => {
        this.$nextTick(() => {
          this.$set(this.menuTree[0], 'children', res.data)
          this.viewLoading = false
        })
      }).catch(err => {
        this.menuTree = []
        this.viewLoading = false
      })
    },
    filterNode(value, data) {
      if (!value) return true
      return data.name.indexOf(value) !== -1
    },
    /**
       * 添加节点
       */
    handleAddButton(data) {
      this.dialogStatus = 'addButton'
      resetTemp(this.temp)
      this.temp.parent = data
      this.temp.parent_name = data.name
      this.temp.parent_id = data.id
      this.temp.type = this.defaultType(data.type)
      this.temp.sort = 10
      this.showMenu = true
      this.dialogFormVisible = true
      this.btnTypeValid(data.type)
      this.$nextTick(() => this.$refs['dataForm'].clearValidate())
    },
    addButton() {
      this.$refs['dataForm'].validate((valid) => {
        if (!valid) return
        this.temp.is_show = this.showMenu ? 1 : 0
        const data = Object.assign({}, this.temp)// copy obj
        if (!data.parent_id) {
          delete data.parent_id
        }
        if (data.parent) { delete data.parent }
        if (data.children) { delete data.children }
        menuApi.insertMenuItem(data).then(() => {
          this.dialogFormVisible = false
          this.fetchData()
          this.$message.success('添加节点成功')
        })
      })
    },
    findMenuTag(childs, mid) {
      if (!childs.length) { return null }
      if (!mid) {return this.menuTree[0]}
      for (const tag of childs) {
        if (tag.id === mid) { return tag }
        if (tag.children) {
          const corg = this.findMenuTag(tag.children, mid)
          if (corg) { return corg }
        }
      }
    },
    /**
       * 更新按钮权限
       */
    handleUpdateButton(data) {
      this.dialogStatus = 'updateButton'
      this.temp = Object.assign({}, data) // copy obj
      this.showMenu = Boolean(this.temp.is_show)
      const parent = this.findMenuTag(this.menuTree, this.temp.parent_id)
      this.temp.parent = parent
      this.temp.parent_name = parent.name
      if (!this.temp.hasOwnProperty('icon')) {
        setTimeout(() => {
          this.$set(this.temp, 'icon', null)
        }, 100)
      }
      this.dialogFormVisible = true
      this.btnTypeValid(data.type)
      this.$nextTick(() => this.$refs['dataForm'].clearValidate())
    },
    updateButton() {
      this.$refs['dataForm'].validate((valid) => {
        if (!valid) return
        this.temp.is_show = this.showMenu ? 1 : 0
        const data = Object.assign({}, this.temp)// copy obj
        if (data.parent) { delete data.parent }
        if (data.children) { delete data.children }
        menuApi.updateMenuItem(data).then(res => {
          this.dialogFormVisible = false
          this.fetchData()
          this.$message.success('更新节点成功')
        })
      })
    },
    tenantChange(val) {
      console.log(val)
      this.$store.dispatch('ActiveTenement', val).then(res => {
        resetTemp(this.tablePage)
        this.fetchData()
      })
    },
    /**
       * 删除按钮权限
       */
    handleDeleleButton(data) {
      this.$confirm('您确定要永久删除该节点？', '提示', confirm).then(() => {
        menuApi.deleteMenuItem(data.id).then(() => {
          this.fetchData()
          this.$message.success('删除节点成功')
        })
      }).catch(() => {
        this.$message({ type: 'info', message: '已取消删除' })
      })
    },
    btnTypeValid(mType) {
      resetTemp(this.enableType)
      if (mType === menuType.TOP) { this.enableType.menuEnable = true } else if (mType === menuType.MENU && this.dialogStatus === 'updateButton') {
        this.enableType.menuEnable = true
        this.enableType.itemEnable = true
        this.enableType.buttonEnable = true
      } else {
        this.enableType.itemEnable = true
        this.enableType.buttonEnable = true
      }
    },
    defaultType(type) {
      if (type === menuType.TOP) { return menuType.MENU }
      return menuType.BUTTON
    },
    buttonName(typeName, type, single = false) {
      if (typeName === buttonType.ADD || !typeName) {
        if (type === menuType.MENU) {
          return !single ? typeName + '子菜单或按钮' : '子菜单或按钮'
        } else if (type === menuType.ITEM) {
          return !single ? typeName + '子菜单或按钮' : '子菜单或按钮'
        }
        return !single ? typeName + '一级菜单' : '一级菜单'
      } else {
        if (type === menuType.MENU) {
          return !single ? typeName + '一级菜单' : '一级菜单'
        } else if (type === menuType.ITEM) {
          return !single ? typeName + '子菜单' : '子菜单'
        } else { return !single ? typeName + '按钮' : '按钮' }
      }
    }

  }
}
</script>

<style rel="stylesheet/scss" lang="scss" scoped>
  @import 'src/styles/variables.scss';
  .mgl-10 {
      margin-left: 10px;
    }
  .top-title{
    font-weight: bold;
    color: $top-color;
  }
  .menu-title{
    font-weight: normal;
    color:$tenant-color;
  }
  .item-title{
    font-weight: lighter;
    color: $company-color;
    font-size: small;
  }
  .button-title{
    font-weight: lighter;
    color: $organize-color;
    font-size: small;
  }
  .title-box {
    display: flex;
    justify-content: space-between;
    align-items: center;
    span {
      font-size: 22px;
    }
  }
  .custom-tree-node {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: space-between;
    font-size: 14px;
    padding-right: 8px;
  }
  .mgb-15 {
    margin-bottom: 15px;
  }
  .grid {
    height: 540px;
    position: relative;
    display: grid;
    overflow-y: scroll;
    overflow-x: hidden;
    grid-template-columns: repeat(auto-fill, minmax(90px, 1fr));
  }
  .icon-item {
    margin: 20px;
    height: 85px;
    text-align: center;
    width: 100px;
    float: left;
    font-size: 30px;
    color: #24292e;
    cursor: pointer;
  }
</style>
